class IUP
	-- Class to handle the interface system of an iup application

inherit
	ANY

create {IUP_INTERFACE}
	init

feature {IUP_INTERFACE}
	
	init
		-- Init the interface system
		do
			--io.put_string("Init IUP%N")
			create objects.make
		end

feature {IUP_GET_PARAM}

	set_get_param (wgt: IUP_GET_PARAM)
		do
			get_param := wgt
		end

feature {ANY}

	-- Commands to init the main loop, exit the loop and close the interface 
	-- system.
			
   main_loop
	   -- Executes the user interaction until a callback returns IUP_CLOSE, 
	   -- "exit_loop" is called, or hiding the last visible dialog.
		-- If you cascade many calls to "main_loop" there must be a 
		-- "return IUP_CLOSE" or "exit_llop" call for each cascade level, hiddinh 
		-- all dialogs will close only one level. Call "main_loop_level" to 
		-- obtain the current level.
		--
		-- If "main_loop" is called without any visible dialogs and no active 
		-- timers, the application will hang and will not be possible to close the 
		-- main loop. The process will have to be interrupted by the 
		-- system.
		--
		-- When the last visible dialog is hidden the "exit_loop" function is 
		-- automatically called, causing the "main_loop" to return. To avoid that 
		-- set the global attribute LOCKLOOP=YES before hiding the last dialog.
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupMainLoop()"
         }"
      end

	main_loop_level: INTEGER
		-- Returns the current cascade level of main loop. When no calls were 
		-- done, return value is 0.
		-- You can use this function to check if "main_loop" was already 
		-- called and avoid calling it again.
		--
		-- A call to "popup" will increase one level.
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupMainLoopLevel()"
         }"
      end

	loop_step: STRING
		-- Runs one iteration of the message loop. Returns immediately 
		-- after	processing any messages or if there are no messages to process.
		--
		-- Returns: IUP_CLOSE or IUP_DEFAULT.
		--
		-- This function is useful for allowing a second message loop to be 
		-- managed by the application itself. This means that messages can be 
		-- intercepted and callbacks can be processed inside an application loop.
		--
		-- If IUP_CLOSE is returned "main" loop will not end because the 
		-- return code was already processed. If you want to end main loop 
		-- when IUP_CLOSE is returned by "loop_step" then call "exit_loop" 
		-- after "loop_step" returns.
		local
			rtn: INTEGER
		do
			rtn := int_loop_step

			if rtn.is_equal(-2) then
				Result := "IUP_DEFAULT"
			else
				Result := "IUP_CLOSE"
			end
		end

	loop_step_wait: STRING
		-- Put the system in idle until a message is processed.
		local
			rtn: INTEGER
		do
			rtn := int_loop_step_wait

			if rtn.is_equal(-2) then
				Result := "IUP_DEFAULT"
			else
				Result := "IUP_CLOSE"
			end
		end

	flush
		-- Processes all pending messages in the message queue.
		-- When you change an attribute of a certain element, the change may not 
		-- take place immediately. For this update to occur faster than usual, 
		-- call "flush" after the attribute is changed.
		--
		-- Important: A call to this function may cause other callbacks to be 
		-- processed before it returns.
		--
		-- In Motif, if the X server sent an event which is not yet in the event 
		--queue, after a call to "flush" the queue might not be empty.
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupFlush()"
         }"
      end

	exit_loop
		-- Exit current loop.
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupExitLoop()"
         }"
      end

   close
	   -- Close the interface system
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupClose()"
         }"
      end

	-- Help

	help (url: STRING): INTEGER
		-- Opens the given URL. In UNIX executes Netscape, Safari (MacOS) or 
		-- Firefox (in Linux) passing the desired URL as a parameter. In Windows 
		-- executes the shell "open" operation on the given URL.
		--
		-- In UNIX you can change the used browser setting the environment 
		-- variable IUP_HELPAPP or using the global attribute "HELPAPP".
		--
		-- It is a non synchronous operation, i.e. the function will return just 
		-- after execute the command and it will not wait for its result.
		--
		-- url: may be any kind of address accepted by the Browser, that is, it 
		-- can include 'http://', or be just a file name, etc.
		--
		-- Returns: 1 if successful, -1 if failed. In Windows can return -2 if
		-- file not found.
		do
			Result := int_help(url.to_external)
		end

	-- Load images

	load_images
		-- Load a pre-defined stock images for buttons and labels.
		-- See: http://webserver2.tecgraf.puc-rio.br/iup/en/iupimglib.html
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupImageLibOpen()"
         }"
      end

	load_iup_controls
		-- Allow use the additional controls, must be called after "iup_open". 
		-- Several additional controls are included in this library. These 
		-- controls are drawn by IUP using CD on a IUP_CANVAS control, and are 
		-- not native controls.
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupControlsOpen()"
         }"
      end

	-- Focus
	
	get_focus: IUP_WIDGET
		-- Returns the interface element that has the keyboard focus, i.e. the 
		-- element that will receive keyboard events (or Void if no element has 
		-- the focus).
		local
			p: POINTER
		do
			p := int_get_focus

			if p.is_not_null then
				Result := widget_for_object(p)
			end
		end

	-- Command to handle global attributes

	set_global_attribute (name: STRING; value: STRING)
		do
			int_set_global (name.to_external, value.to_external)
		end

	get_global_attribute (name: STRING): STRING
		local
			str: STRING
		do
			create str.from_external_copy(int_get_global (name.to_external))
			Result := str
		end

	-- Global attribute PARENTDIALOG and ICON

	set_global_parent_dialog_widget (dlg: IUP_DIALOG)
		-- Parent dialog to be used in some predefined dialogs.
		local
			p: POINTER
			str: STRING
		do
			str := once "PARENTDIALOG"
			int_set_attribute_handle (p, str.to_external, dlg.widget)
		end

	set_global_icon_widget (icon: IUP_IMAGE)
		-- Icon to be used in some predefined dialogs.
		local
			p: POINTER
			str: STRING
		do
			str := once "ICON"
			int_set_attribute_handle (p, str.to_external, icon.widget)
		end

	-- Copy attributes

	copy_attributes(src, dst: IUP_WIDGET)
		-- Copies all hash table attributes from one element to another.
		-- Internal attributes or handle attributes are not copied.
		--
		-- src: identifier of the source element.
		--	dst: identifier of the destiny element.
		do
			int_copy_attributes(src.widget, dst.widget)
		end

	-- Global attributes: General

	set_language_english
		do
			set_global_attribute ("LANGUAGE", "ENGLISH")
		end

	set_language_spanish
		do
			set_global_attribute ("LANGUAGE", "SPANISH")
		end

	set_language_portuguese
		do
			set_global_attribute ("LANGUAGE", "PORTUGUESE")
		end

	set_language (language: STRING)
		-- Sets the language name used by some pre-defined dialogs.
		--
		-- All elements that have pre-defined texts. The native dialogs like 
		-- IUP_FILE_DIALOG will always be displayed in the system language.
		--
		-- Even if the language is not supported (meaning its pack of pre-defined 
		-- strings are not defined) the new language name will be successfully 
		-- stored so you can set your own strings and return a coherent value, 
		-- and the current defined string will not be changed.
		--
		-- Here is a list of the pre-defined string names:
		-- IUP_ERROR, IUP_ATTENTION, IUP_YES, IUP_NO, IUP_INVALIDDIR, 
		-- IUP_FILEISDIR, IUP_FILENOTEXIST, IUP_FILEOVERWRITE, IUP_CREATEFOLDER,
		-- IUP_NAMENEWFOLDER, IUP_SAVEAS, IUP_OPEN, IUP_SELECTDIR, IUP_OK,
		-- IUP_CANCEL, IUP_RETRY, IUP_APPLY, IUP_RESET, IUP_GETCOLOR, IUP_HELP,
		-- IUP_RED, IUP_GREEN, IUP_BLUE, IUP_HUE, IUP_SATURATION, IUP_INTENSITY,
		-- IUP_OPACITY, IUP_PALETTE, IUP_TRUE, IUP_FALSE, IUP_FAMILY, IUP_STYLE,
		-- IUP_SIZE, IUP_SAMPLE, IUP_ERRORFILEOPEN, IUP_ERRORFILESAVE
		do
			set_global_attribute ("LANGUAGE", language)
		end

	get_language: STRING
		do
			Result := get_global_attribute("LANGUAGE")
		end

	set_language_string (name, value: STRING)
		-- Associates a name with a string as an auxiliary method for 
		-- Internationalization of applications.
		--
		-- name: name of the string.
		-- value: string value.
		--
		-- This will store the pointer. Elements that have pre-defined texts use 
		-- this function when the current language is changed.
		--
		-- IUP will not store strings for several languages at the same time, it 
		-- will store only for the current language. When "set_language" is 
		-- called only the internal pre-defined strings are replace in the 
		-- internal database. The application must register again all its strings 
		-- for the new language.
		--
		-- If a dialog is created with string names associations and the 
		-- associations are about to be changed, then the dialog must be 
		-- destroyed before the associations are changed, then created again.
		--
		-- Associations are retrieved using the "get_language_string" feature. 
		-- But to simplify the usage of the string names associations attributes 
		-- set with regular IupSetStr* functions can use the prefix "_@" to 
		-- indicate a string name and not the actual string.
		do
			int_set_language_string(name.to_external, value.to_external)
		end

	store_language_string (name, value: STRING)
		-- Like "set_language_string" but will duplicate the string internally.
		do
			int_store_language_string(name.to_external, value.to_external)
		end

	get_language_string(name: STRING): STRING
		-- Returns a language dependent string.
		local
			str: STRING
		do
			create str.from_external_copy(int_get_language_string(name.to_external))
			Result := str
		end

	--set_language_pack (pack: IUP_USER)
		-- Sets a pack of associations between names and string values. 
		-- Internally will call "set_language_string" for each name in the pack.
		--
		-- After setting the pack it can be destroyed. The existent associations 
		-- will not be removed. But if the new ones have the same names, the old 
		-- ones will be replaced.
	--	do
	--		int_set_language_pack(pack.widget)
	--	end

	--remove_language_pack
		-- Remove all current associations.
	--	local
	--		p: POINTER
	--	do
	--		int_set_language_pack(p)
	--	end

	get_driver: STRING
		-- Informs the current driver being used. Two drivers are available now, 
		-- one for each platform: "GTK", "Motif" and "Win32".
		do
			Result := get_global_attribute("DRIVER")
		end

	-- Global attributes: System

	set_lock_loop_yes
		-- When the last visible dialog is closed the IupExitLoop function is 
		-- called. To avoid that call this feature before hiding the last dialog.
		do
			set_global_attribute ("LOCKLOOP", "YES")
		end

	set_lock_loop_no
		do
			set_global_attribute ("LOCKLOOP", "NO")
		end

	set_exit_loop_yes
		-- Disable the "exit_loop" function when "main_loop_level" return 1. Used 
		-- when the application runs secondary dialogs that behave as full 
		-- applications but sharing the same IUP environment,
		do
			set_global_attribute ("EXITLOOP", "YES")
		end

	set_exit_loop_no
		do
			set_global_attribute ("EXITLOOP", "NO")
		end

	set_default_precision (value: INTEGER)
		-- The default number of decimal places used in floating point output by 
		-- some controls (IUP_MATRIX and IUP_GET_PARAM). Local attributes may 
		-- overwrite the default. Default: 2.
		do
			set_global_attribute ("DEFAULTPRECISION", value.to_string)
		end

	get_default_precision: INTEGER
		local
			str: STRING
		do
			str := get_global_attribute("DEFAULTPRECISION")

			Result := str.to_integer
		end

	set_default_decimal_symbol_period
		do
			set_global_attribute ("DEFAULTDECIMALSYMBOL", ".")
		end

	set_default_decimal_symbol_comma
		do
			set_global_attribute ("DEFAULTDECIMALSYMBOL", ",")
		end

	is_default_decimal_symbol_period: BOOLEAN
		local
			str: STRING
		do
			str := get_global_attribute("DEFAULTPRECISION")

			if str.is_equal(".") then
				Result := True
			else
				Result := False
			end
		end

	is_default_decimal_symbol_comma: BOOLEAN
		local
			str: STRING
		do
			str := get_global_attribute("DEFAULTPRECISION")

			if str.is_equal(",") then
				Result := True
			else
				Result := False
			end
		end

	set_global_menu (state: BOOLEAN)
		-- [GTK Only] Flag indicating that GTK is using a global menu instead of 
		-- a per window menu.	
		do
			set_global_attribute ("GLOBALMENU", boolean_to_yesno(state))
		end

	-- Default attributes

	set_default_theme (name: STRING)
		do
			set_global_attribute ("DEFAULTTHEME", name)
		end

	-- System Mouse and Keyboard

	set_cursor_position (x, y: INTEGER)
		-- Controls the cursor position in absolute coordinates relative to the 
		-- origin of the main screen. The origin of the main screen is at the 
		-- upper left corner, in Windows it is affected by the position of the 
		-- Start Menu when it is at the top or left side of the screen. In GTK 
		-- and Motif also generates mouse motion messages.
		local
			str: STRING
		do
			create str.copy(x.to_string)
	      str.append_string("x")
 	      str.append_string(y.to_string)
	
			set_global_attribute("CURSORPOS", str)
		end

	get_cursor_position: TUPLE[INTEGER, INTEGER]
		local
			str: STRING
		do
			str := get_global_attribute("CURSORPOS")
			
			Result := components_of (str, 'x')
		end

	get_shift_key_state: BOOLEAN
		local
			str: STRING
		do
			str := get_global_attribute("SHIFTKEY")

			Result := yesno_to_boolean(str)
		end

	get_control_key_state: BOOLEAN
		local
			str: STRING
		do
			str := get_global_attribute("CONTROLKEY")

			Result := yesno_to_boolean(str)
		end

	get_modifier_keys_state: STRING
		-- Returns the state of the keyboard modifier keys: Shift, Ctrl, Alt and 
		-- sYs(Win/Apple). In the format of 4 characters: "SCAY". When not 
		-- pressed the respective letter is replaced by a space " ". 
		do
			Result := get_global_attribute("MODKEYSTATE")
		end

	-- Key codes

	is_print_key (key: INTEGER): BOOLEAN
		-- Informs if a key can be directly used as a printable character.
		local
			rv: INTEGER
		do
			rv := int_is_print_key(key)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_x_key (key: INTEGER): BOOLEAN
		-- Informs if a given key is an extended code (ASCII code >= 128).
		local
			rv: INTEGER
		do
			rv := int_is_x_key(key)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end
	
	is_shift_x_key (key: INTEGER): BOOLEAN
	-- Informs if a given key is an extended code using the Shift modifier.
		local
			rv: INTEGER
		do
			rv := int_is_shift_x_key(key)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_ctrl_x_key (key: CHARACTER): BOOLEAN
	-- Informs if a given key is an extended code using the Ctrl modifier.
		local
			rv: INTEGER
		do
			rv := int_is_ctrl_x_key(key)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_alt_x_key (key: CHARACTER): BOOLEAN
		--	Informs if a given key is an extended code using the Alt modifier.
		local
			rv: INTEGER
		do
			rv := int_is_alt_x_key(key)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_sys_x_key (key: CHARACTER): BOOLEAN
		-- Informs if a given key is an extended code using the Sys modifier.
		-- Sys in Windows is the Windows key and in Mac is the Apple key.
		local
			rv: INTEGER
		do
			rv := int_is_sys_x_key(key)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	x_key_base (key: CHARACTER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_XkeyBase"
         }"
      end

	x_key_shift (key: CHARACTER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_XkeyShift"
         }"
      end

	x_key_ctrl (key: CHARACTER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_XkeyCtrl"
         }"
      end

	x_key_alt (key: CHARACTER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_XkeyAlt"
         }"
      end

	x_key_sys (key: CHARACTER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_XkeySys"
         }"
      end

	-- Mouse buttons

	is_shift (status: STRING): BOOLEAN
		local
			a: NATIVE_ARRAY[CHARACTER]
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_shift(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_control (status: STRING): BOOLEAN
		local
			a: NATIVE_ARRAY[CHARACTER]
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_control(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_button_1 (status: STRING): BOOLEAN
		local
			a: NATIVE_ARRAY[CHARACTER]
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_button_1(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_button_2 (status: STRING): BOOLEAN
		local
			a: NATIVE_ARRAY[CHARACTER]
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_button_2(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_button_3 (status: STRING): BOOLEAN
		local
			a: NATIVE_ARRAY[CHARACTER]
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_button_3(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_button_4 (status: STRING): BOOLEAN
		local
			a: NATIVE_ARRAY[CHARACTER]
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_button_4(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_button_5 (status: STRING): BOOLEAN
		local
			a: NATIVE_ARRAY[CHARACTER]
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_button_5(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_double (status: STRING): BOOLEAN
		local
			a: NATIVE_ARRAY[CHARACTER]
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_double(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_alt (status: STRING): BOOLEAN
		local
			a: NATIVE_ARRAY[CHARACTER]
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_alt(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	is_sys (status: STRING): BOOLEAN
		local
			a: NATIVE_ARRAY[CHARACTER]
			rv: INTEGER
		do
			a := convert_string_to_array(status)
			rv := int_is_sys(a)
			
			if rv.is_equal(0) then
				Result := False
			else
				Result := True
			end
      end

	-- CD

	init_context_plus
		external "plug_in"
		alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "cdInitContextPlus()"
         }"
      end

	use_context_plus (status: BOOLEAN): BOOLEAN
		local
			prev: INTEGER
		do
			if status then
				prev := int_use_context_plus(1)
			else
				prev := int_use_context_plus(0)
			end

			if prev.is_equal (0) then
				Result := False
			else
				Result := True
			end
		end

feature {IUP_WIDGET, IUP_CLIPBOARD}

	-- Converts

	position_to_integer (i: STRING): INTEGER
		do
			if i.is_equal("IUP_CENTER") then
				Result := 65535
			elseif i.is_equal("IUP_LEFT") or i.is_equal("IUP_TOP") then
				Result := 65534
			elseif i.is_equal("IUP_RIGHT") or i.is_equal("IUP_BOTTOM") then
				Result := 65533
			elseif i.is_equal("IUP_MOUSEPOS") then
				Result := 65532
			elseif i.is_equal("IUP_CURRENT") then
				Result := 65531
			elseif i.is_equal("IUP_CENTERPARENT") then
				Result := 65530
			else
				Result := i.to_integer
			end
		end

	-- PopUp a dialog or menu

	popup_predefined_xy (wgt: IUP_WIDGET; x, y: STRING): STRING
		-- Displays a dialog or menu in a given position on the screen using 
		-- predefined values. However you can combine a predefined value with 
		-- an integer (as string).If there was an error returns IUP_ERROR.
		--
		-- wgt: Identifier of a dialog or a menu.
		-- x: The following predefined values can be used:
		--
		--  IUP_LEFT: Positions the dialog on the left corner of the main screen
		--  IUP_CENTER: Horizontally centralizes the dialog on the main screen
		--  IUP_RIGHT: Positions the dialog on the right corner of the main screen
		--  IUP_MOUSEPOS: Positions the dialog on the mouse position
		--  IUP_CENTERPARENT: Horizontally centralizes the dialog relative to its 
		--                    parent
		--  IUP_CURRENT: use the current position of the dialog.
		--
		-- y: The following predefined calues can be used:
		--
		-- IUP_TOP: Positions the dialog on the top of the main screen
		-- IUP_CENTER: Vertically centralizes the dialog on the main screen
		-- IUP_BOTTOM: Positions the dialog on the base of the main screen
		-- IUP_MOUSEPOS: Positions the dialog on the mouse position
		-- IUP_CENTERPARENT: Vertically centralizes the dialog relative to its 
		--                   parent
		-- IUP_CURRENT: use the current position of the dialog.
		require
			is_valid_position(x, y)
		do
			Result := popup(wgt, position_to_integer(x), position_to_integer(y))
		end

	popup (wgt: IUP_WIDGET; x, y: INTEGER): STRING
		-- Shows a widget and restricts user interaction only to the specified 
		-- element.
		--
		-- wgt: Identifier of a dialog or a menu.
		-- x: horizontal position of the top left corner of the window or menu, 
		--    relative to the origin of the main screen.
		-- y: vertical position of the top left corner of the window or menu, 
		--    relative to the origin of the main screen.
		local
			r: INTEGER
		do
			r := int_popup(wgt.widget, x, y)

			if r.is_equal(-1) then
				Result := "IUP_INVALID"
			elseif r.is_equal(0) then
				Result := "IUP_NOERROR"
			else
				Result := "IUP_ERROR"
			end
		end

	-- Commands to handle objects and callbacks

	set_widget_for_object (wgt: POINTER; eiffel_object: IUP_WIDGET)
		do
			objects.put(eiffel_object, wgt)

			set_callback (eiffel_object, "LDESTROY_CB", "NONEEDED", 1)
		end

	get_widget_for_object (wgt: POINTER): IUP_WIDGET
		do
			Result := widget_for_object(wgt)
		end

	delete_widget_for_object (wgt: POINTER; eiffel_object: IUP_WIDGET)
		do
			if objects.has(wgt) then
				objects.remove(wgt)
				set_callback(eiffel_object, "LDESTROY_CB", "NONEEDED", 0)
				int_destroy(wgt)
			end
		end

	set_callback (wgt: IUP_WIDGET; name: STRING; type: STRING; operation: INTEGER)
      do
			int_set_callback (wgt.widget, name.to_external, type.to_external, operation)
      end

	set_idle_action (act: FUNCTION[TUPLE, STRING])
		do
			if act /= Void then
				int_set_function ("IDLE_ACTION".to_external, 1)
			else
				int_set_function ("IDLE_ACTION".to_external, 0)
			end

			idle_action := act
		end

	-- Commands to handle the hierarchy and management
	
	iup_append (control: IUP_WIDGET; new_child: IUP_WIDGET): IUP_WIDGET
	   -- Insert a new widget at the end, return the object of the 
	   -- actual parent.
		local
			p: POINTER
		do
			p := int_append(control.widget, new_child.widget)
			Result := widget_for_object(p)
		end

	iup_detach (control: IUP_WIDGET)
		-- Detaches an interface element from its parent.
		do
			int_detach(control.widget)
		end
		
	iup_insert (control: IUP_WIDGET; ref_child: IUP_WIDGET; new_child: IUP_WIDGET): IUP_WIDGET
	   -- Insert a new widget before the reference widget, return the 
	   -- object of the actual parent.
		local
			p: POINTER
		do
			p := int_insert(control.widget, ref_child.widget, new_child.widget)
			Result := widget_for_object(p)
		end

	iup_reparent (child: IUP_WIDGET; new_parent: IUP_WIDGET; ref_child: IUP_WIDGET): STRING
		-- Moves an interface element from one position in the hierarchy
		-- tree to another.
		local
			r: INTEGER
		do
			r := int_reparent(child.widget, new_parent.widget, ref_child.widget)

			if r.is_equal(0) then
				Result := "IUP_NOERROR"
			else
				Result := "IUP_ERROR"
			end
		end

	iup_get_parent (child: IUP_WIDGET): IUP_WIDGET
		-- Returns the parent of a control.
		local
			p: POINTER
		do
			p := int_get_parent(child.widget)
			Result := widget_for_object(p)
		end

	iup_get_child (control: IUP_WIDGET; position: INTEGER): IUP_WIDGET
		-- Returns the a child of the control given its position
		-- or NULL if there is none.
		local
			p: POINTER
		do
			p := int_get_child(control.widget, position)
			Result := widget_for_object(p)
		end

	iup_get_child_pos (control: IUP_WIDGET; child: IUP_WIDGET): INTEGER
		-- Returns the position of a child of the given control.
		-- The position of the desire child starting at 0, or -1 if child 
		-- not found.
		do
			Result := int_get_child_pos(control.widget, child.widget)
		end

	iup_get_child_count (control: IUP_WIDGET): INTEGER
		-- Returns the number of children of the given control.
		do
			Result := int_get_child_count(control.widget)
		end

	iup_get_next_child (control: IUP_WIDGET; child: IUP_WIDGET): IUP_WIDGET
		-- Returns the a child of the given control given its brother.
		-- Returns the handle of the child or Void.
		local
			p: POINTER
		do
			p := int_get_next_child(control.widget, child.widget)
			Result := widget_for_object(p)
		end

	iup_get_brother (control: IUP_WIDGET): IUP_WIDGET
		-- Returns the brother of an element.
		-- Returns the brother or Void if there is none.
		local
			p: POINTER
		do
			p := int_get_brother(control.widget)
			Result := widget_for_object(p)
		end

	iup_get_dialog (control: IUP_WIDGET): IUP_DIALOG
		-- Returns the handle of the dialog that contains that interface
		-- element (or NULL if not found). Works also for children of a 
		-- menu that is associated with a dialog.
		local
			p: POINTER
			dlg: IUP_DIALOG
		do
			p := int_get_dialog(control.widget)
			dlg ?= widget_for_object(p)

			if dlg /= Void then
				Result := dlg
			end
		end

	iup_get_dialog_child (control: IUP_WIDGET; name: STRING): IUP_WIDGET
		-- Returns the identifier of the child element that has the NAME
		-- attribute equals to the given value on the same dialog 
		-- hierarchy (or void if not found). Works also for children of a 
		-- menu that is associated with a dialog.
		local
			p: POINTER
		do
			p := int_get_dialog_child(control.widget, name.to_external)
			Result := widget_for_object(p)
		end

	iup_refresh (control: IUP_WIDGET)
		-- Updates the size and layout of all controls in the same dialog.
		do
			int_refresh(control.widget)
		end

	iup_refresh_children (control: IUP_WIDGET)
		-- Updates the size and layout of controls after changing size
		-- attributes, or attributes that affect the size of the control. 
		-- Can be used for any element inside a dialog, only its children 
		-- will be updated. It can change the layout of all the controls
		-- inside the given element because of the dynamic layout positioning.
		do
			int_refresh_children(control.widget)
		end
	
	iup_update (control: IUP_WIDGET)
		-- Mark the element to be redraw when the control returns 
		-- to the system.
		do
			int_update(control.widget)
		end

	iup_update_children (control: IUP_WIDGET)
		-- Mark element children to be redraw when the control returns 
		-- to the system.
		do
			int_update_children(control.widget)
		end

	iup_redraw (control: IUP_WIDGET; flag: INTEGER)
		-- Force the element and its children to be redrawn immediately.
		do
			int_redraw(control.widget, flag)
		end

	iup_convert_xy_to_pos(control: IUP_WIDGET; x, y: INTEGER): INTEGER
		do
			Result := int_convert_xy_to_pos(control.widget, x, y)
		end

	-- Commands to handle attributes
		
	set_attribute (wgt: IUP_WIDGET; name: STRING; value: STRING)
		do
			int_set_attribute (wgt.widget, name.to_external, value.to_external)
		end

	set_attribute_in_handle (handle: POINTER; name: STRING; value: STRING)
		do
			int_set_attribute (handle, name.to_external, value.to_external)
		end

	set_attribute_widget (wgt: IUP_WIDGET; name: STRING; other_wgt: IUP_WIDGET)
		do
			int_set_attribute_handle (wgt.widget, name.to_external, other_wgt.widget)
		end

	set_attribute_null (wgt: IUP_WIDGET; name: STRING)
		local
			p: POINTER
		do
			int_set_attribute (wgt.widget, name.to_external, p)
		end

	set_attribute_null_in_handle (wgt: POINTER; name: STRING)
		local
			p: POINTER
		do
			int_set_attribute (wgt, name.to_external, p)
		end

	set_str_attribute (wgt: IUP_WIDGET; name: STRING; value: STRING)
		do
			int_set_str_attribute (wgt.widget, name.to_external, value.to_external)
		end

	set_attribute_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER; value: STRING)
		do
			int_set_attribute_id (wgt.widget, name.to_external, id, value.to_external)
		end

	set_str_attribute_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER; value: STRING)
		do
			int_set_str_attribute_id (wgt.widget, name.to_external, id, value.to_external)
		end

	set_attribute_id2 (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER; value: STRING)
		do
			int_set_attribute_id2 (wgt.widget, name.to_external, lin, col, value.to_external)
		end

	set_attribute_id2_null (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER)
		local
			p: POINTER
		do
			int_set_attribute_id2 (wgt.widget, name.to_external, lin, col, p)
		end

	set_str_attribute_id2 (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER; value: STRING)
		do
			int_set_str_attribute_id2 (wgt.widget, name.to_external, lin, col, value.to_external)
		end

	set_int (wgt: IUP_WIDGET; name: STRING; value: INTEGER)
		do
			int_set_int (wgt.widget, name.to_external, value)
		end

	set_float (wgt: IUP_WIDGET; name: STRING; value: REAL_32)
		do
			int_set_float (wgt.widget, name.to_external, value)
		end

	set_double (wgt: IUP_WIDGET; name: STRING; value: REAL_64)
		do
			int_set_double (wgt.widget, name.to_external, value)
		end

	set_rgb (wgt: IUP_WIDGET; name: STRING; r: CHARACTER; g: CHARACTER; b: CHARACTER)
		do
			int_set_rgb (wgt.widget, name.to_external, r, g, b)
		end

	set_int_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER; value: INTEGER)
		do
			int_set_int_id (wgt.widget, name.to_external, id, value)
		end

	set_float_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER; value: REAL_32)
		do
			int_set_float_id (wgt.widget, name.to_external, id, value)
		end

	set_double_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER; value: REAL_64)
		do
			int_set_double_id (wgt.widget, name.to_external, id, value)
		end

	set_rgb_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER; r: CHARACTER; g: CHARACTER; b: CHARACTER)
		do
			int_set_rgb_id (wgt.widget, name.to_external, id, r, g, b)
		end

	set_int_id2 (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER; value: INTEGER)
		do
			int_set_int_id2 (wgt.widget, name.to_external, lin, col, value)
		end

	set_float_id2 (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER; value: REAL_32)
		do
			int_set_float_id2 (wgt.widget, name.to_external, lin, col, value)
		end

	set_double_id2 (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER; value: REAL_64)
		do
			int_set_double_id2 (wgt.widget, name.to_external, lin, col, value)
		end

	set_rgb_id2 (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER; r: CHARACTER; g: CHARACTER; b: CHARACTER)
		do
			int_set_rgb_id2 (wgt.widget, name.to_external, lin, col, r, g, b)
		end

	reset_attribute (wgt: IUP_WIDGET; name: STRING)
		do
			int_reset_attribute (wgt.widget, name.to_external)
		end

	set_attribute_handle (wgt: IUP_WIDGET; name: STRING; wgt_named: IUP_WIDGET)
		do
			int_set_attribute_handle (wgt.widget, name.to_external, wgt_named.widget)
		end

	get_attribute (wgt: IUP_WIDGET; name: STRING): STRING
		local
			p: POINTER
			str: STRING
		do
			p := int_get_attribute (wgt.widget, name.to_external)

			if p.is_not_null then
				create str.from_external_copy(p)
				Result := str
			else
				Result := ""
			end
		end

	get_attribute_from_handle (handle: POINTER; name: STRING): STRING
		local
			p: POINTER
			str: STRING
		do
			p := int_get_attribute (handle, name.to_external)

			if p.is_not_null then
				create str.from_external_copy(p)
				Result := str
			end
		end

	get_attribute_widget (wgt: IUP_WIDGET; name: STRING): IUP_WIDGET
		local
			p: POINTER
		do
			p := int_get_attribute (wgt.widget, name.to_external)
			Result := widget_for_object(p)
		end

	get_attribute_ihandle (wgt: IUP_WIDGET; name: STRING): POINTER
		do
			Result := int_get_attribute (wgt.widget, name.to_external)
		end

	get_attribute_ihandle_from_handle (handle: POINTER; name: STRING): POINTER
		do
			Result := int_get_attribute (handle, name.to_external)
		end

	get_attribute_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER): STRING
		local
			p: POINTER
			str: STRING
		do
			p := int_get_attribute_id (wgt.widget, name.to_external, id)

			if p.is_not_null then
				create str.from_external_copy(p)
				Result := str
			else
				Result := ""
			end
		end

	get_attribute_id2 (wgt: IUP_WIDGET; name: STRING; lin: INTEGER; col: INTEGER): STRING
		local
			p: POINTER
			str: STRING
		do
			p := int_get_attribute_id2 (wgt.widget, name.to_external, lin, col)

			if p.is_not_null then
				create str.from_external_copy(p)
				Result := str
			else
				Result := ""
			end
		end

	get_int (wgt: IUP_WIDGET; name: STRING): INTEGER
		do
			Result := int_get_int (wgt.widget, name.to_external)
		end

	get_int_int (wgt: IUP_WIDGET; name: STRING; i1: POINTER; i2: POINTER): TUPLE[INTEGER, INTEGER]
		local
			count: INTEGER
			tup: TUPLE[INTEGER, INTEGER]
		do
			count := int_get_int_int (wgt.widget, name.to_external, i1, i2)

			tup := [i1.to_string.to_integer, i2.to_string.to_integer]
			Result := tup
		end
	
	get_int2 (wgt: IUP_WIDGET; name: STRING): INTEGER
		do
			Result := int_get_int2 (wgt.widget, name.to_external)
		end

	get_float (wgt: IUP_WIDGET; name: STRING): REAL_32
		do
			Result := int_get_float (wgt.widget, name.to_external)
		end

	get_double (wgt: IUP_WIDGET; name: STRING): REAL_64
		do
			Result := int_get_double (wgt.widget, name.to_external)
		end

	get_rgb (wgt: IUP_WIDGET; name: STRING): TUPLE[INTEGER, INTEGER, INTEGER]
		local
			color: STRING
			values: ARRAY[STRING]
			tup: TUPLE[INTEGER, INTEGER, INTEGER]
		do
			color := get_attribute(wgt, name)

			values := color.split

			if values.count.is_equal(3) then
				
				if values.item(1).is_integer and
					values.item(2).is_integer and
					values.item(3).is_integer then
					tup := [values.item(1).to_integer, values.item(2).to_integer,
					        values.item(3).to_integer]
					Result := tup
				else
					io.put_string("Something goes wrong %N")
				end
			end
		end

	get_rgba (wgt: IUP_WIDGET; name: STRING): TUPLE[INTEGER, INTEGER, INTEGER, INTEGER]
		local
			color: STRING
			values: ARRAY[STRING]
			tup: TUPLE[INTEGER, INTEGER, INTEGER, INTEGER]
		do
			color := get_attribute(wgt, name)

			values := color.split

			if values.count.is_equal(3) then
				
				if values.item(1).is_integer and
					values.item(2).is_integer and
					values.item(3).is_integer then
					tup := [values.item(1).to_integer, values.item(2).to_integer,
					        values.item(3).to_integer, 0.to_integer_32]
					Result := tup
				else
					io.put_string("Something goes wrong %N")
				end
			else
				if values.item(1).is_integer and
					values.item(2).is_integer and
					values.item(3).is_integer and
					values.item(4).is_integer then
					tup := [values.item(1).to_integer, values.item(2).to_integer,
					        values.item(3).to_integer, values.item(4).to_integer]
				   Result := tup
				else
					io.put_string("Something goes wrong %N")
				end
			end
		end

	get_rgb_id (wgt: IUP_WIDGET; name: STRING; id: INTEGER): TUPLE[INTEGER, INTEGER, INTEGER]
		local
			color: STRING
			values: ARRAY[STRING]
			tup: TUPLE[INTEGER, INTEGER, INTEGER]
		do
			color := get_attribute_id(wgt, name, id)

			values := color.split

			if values.count.is_equal(3) then
				
				if values.item(1).is_integer and
					values.item(2).is_integer and
					values.item(3).is_integer then
					tup := [values.item(1).to_integer, values.item(2).to_integer,
					        values.item(3).to_integer]
					Result := tup
				else
					io.put_string("Something goes wrong %N")
				end
			end
		end

	get_hsi (wgt: IUP_WIDGET; name: STRING): TUPLE[INTEGER, INTEGER, INTEGER]
		do
			Result := get_rgb(wgt, name)
		end

	get_hsi_real (wgt: IUP_WIDGET; name: STRING): TUPLE[REAL_64, REAL_64, REAL_64]
		local
			color: STRING
			values: ARRAY[STRING]
			tup: TUPLE[REAL_64, REAL_64, REAL_64]
		do
			color := get_attribute(wgt, name)

			values := color.split

			if values.count.is_equal(3) then
				
				if values.item(1).is_real and
					values.item(2).is_real and
					values.item(3).is_real then
					tup := [values.item(1).to_real, values.item(2).to_real,
					        values.item(3).to_real]
					Result := tup
				else
					io.put_string("Something goes wrong %N")
				end
			end
		end
	
	get_attribute_handle (wgt: IUP_WIDGET; name: STRING): IUP_WIDGET
		local
			p: POINTER	
		do
			p := int_get_attribute_handle (wgt.widget, name.to_external)
			Result := widget_for_object(p)
		end

feature {IUP}
	
	-- Callbacks
	
	launch_idle_action_fidle: INTEGER
		local
			v: STRING
		do
			if idle_action /= Void then
				v := idle_action.item([])
				Result := return_value(v)
			end
		end

	launch_help_cb_fn (obj: POINTER)
		local
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				iup_widget.execute_help
			end
		end

	launch_map_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_map
				Result := return_value(v)
			end
		end

	launch_unmap_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_unmap
				Result := return_value(v)
			end
		end

	launch_destroy_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_destroy
				Result := return_value(v)
			end
		end

	launch_ldestroy_cb_fn (obj: POINTER): INTEGER
		--local
		--	iup_widget: IUP_WIDGET
		do
			---if objects.has(obj) then
			--	objects.remove(obj)

			--	if objects.has(obj) then
			--		delete_widget_for_object (obj, iup_widget)
			--	end
				
				Result := return_value("IUP_DEFAULT")
			--end
		end

	launch_getfocus_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_getfocus
				Result := return_value(v)
			end
		end

	launch_killfocus_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_killfocus
				Result := return_value(v)
			end
		end

	launch_enterwindow_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_enterwindow
				Result := return_value(v)
			end
		end

	launch_leavewindow_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_leavewindow
				Result := return_value(v)
			end
		end

	launch_k_any_fni (obj: POINTER; int: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_k_any(int)
				Result := return_value(v)
			end
		end

	launch_action_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_action
				Result := return_value(v)
			end
		end

	-- Dialogs
	launch_close_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_close
				Result := return_value(v)
			end
		end

	launch_copydata_cb_fnsi (obj, cmdline: POINTER; size: INTEGER): INTEGER
		local
			v, cl: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if cmdline.is_not_null then
					create cl.from_external_copy(cmdline)
				else
					cl := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_copydata(cl, size)
				Result := return_value(v)
			end
		end

	-- Also for canvas, label, list.
	launch_dropfiles_cb_fnsiii (obj: POINTER; filename: POINTER; num: INTEGER; x: INTEGER; y: INTEGER): INTEGER
		local
			v, file: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				
				if filename.is_not_null then
					create file.from_external_copy(filename)
				else
					file := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_dropfiles(file, num, x, y)
				Result := return_value(v)
			end
		end

	launch_mdiactivate_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_mdiactivate
				Result := return_value(v)
			end
		end

	launch_move_cb_fnii (obj: POINTER; x: INTEGER; y: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_move(x, y)
				Result := return_value(v)
			end
		end

	-- Also for canvas
	launch_resize_cb_fnii (obj: POINTER; width: INTEGER; height: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_resize(width, height)
				Result := return_value(v)
			end
		end

	launch_show_cb_fni (obj: POINTER; state: INTEGER): INTEGER
		local
			v, s: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				
				if state.is_equal(0) then
					s := "IUP_SHOW"
				elseif state.is_equal(1) then
					s := "IUP_RESTORE"
				elseif state.is_equal(2) then
					s := "IUP_MINIMIZE"
				elseif state.is_equal(3) then
					s := "IUP_MAXIMIZE"
				else
					s := "IUP_HIDE"
				end
					
				v := iup_widget.execute_show(s)
				Result := return_value(v)
			end
		end

	launch_trayclick_cb_fniii (obj: POINTER; but: INTEGER; pressed: INTEGER; dclick: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_trayclick(but, pressed, dclick)
				Result := return_value(v)
			end
		end

	-- Callback for file dialog
	launch_file_cb_fnss (obj: POINTER; file_name, status: POINTER): INTEGER
		local
			v, file, st: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if file_name.is_not_null then
					create file.from_external_copy(file_name)
				else
					file := ""
				end

				if status.is_not_null then
					create st.from_external_copy(status)
				else
					st := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_file(file, st)
				Result := return_value(v)
			end
		end

	-- Color update
	launch_colorupdate_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_colorupdate
				Result := return_value(v)
			end
		end

	-- Progress bar dialog
	launch_cancel_cb_fn(obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_cancel
				Result := return_value(v)
			end
		end

	-- Callbacks for tabs
	launch_tabchange_cb_fnnn (obj, new_tab, old_tab: POINTER): INTEGER
		local
			v: STRING
			iup_widget, ntab, otab: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)

				if new_tab.is_not_null then
					ntab := objects.at(new_tab)
				end

				if old_tab.is_not_null then
					otab := objects.at(old_tab)
				end

				v := iup_widget.execute_tabchange(ntab, otab)
				Result := return_value(v)
			end
		end

	launch_tabchangepos_cb_fnii (obj: POINTER; new_pos, old_pos: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_tabchangepos(new_pos, old_pos)
				Result := return_value(v)
			end
		end

	launch_tabclose_cb_fni (obj: POINTER; pos: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_tabclose(pos)
				Result := return_value(v)
			end
		end

	launch_rightclick_cb_fni (obj: POINTER; pos: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_rightclick(pos)
				Result := return_value(v)
			end
		end

	-- Callbacks for DetachBox
	launch_detached_cb_fnnii (obj, new_parent: POINTER; x, y: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
			nparent: IUP_DIALOG
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)

				create nparent.dialog_widget(new_parent)

				v := iup_widget.execute_detached(nparent, x, y)
				Result := return_value(v)
			end
		end

	launch_restored_cb_fnnii (obj, old_parent: POINTER; x, y: INTEGER): INTEGER
		local
			v: STRING
			iup_widget, oparent: IUP_WIDGET
		do
			if objects.has(obj) and objects.has(old_parent) then
				iup_widget := objects.at(obj)
				oparent := objects.at(old_parent)

				v := iup_widget.execute_restored(oparent, x, y)
				Result := return_value(v)
			end
		end

	-- Callbacks for Expander
	launch_openclose_cb_fni (obj: POINTER; state: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_openclose(state)
				Result := return_value(v)
			end
		end

	launch_extrabutton_cb_fnii (obj: POINTER; button, pressed: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_extrabutton(button, pressed)
				Result := return_value(v)
			end
		end

	-- Callback for split, calendar, toggle, val.
	launch_valuechanged_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_valuechanged
				Result := return_value(v)
			end
		end

	-- Callback for button, label, list, text.
	launch_button_cb_fniiiis (obj: POINTER; button, pressed, x, y: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if status.is_not_null then
					create st.from_external_copy(status)
				else
					st := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_button(button.to_character.decimal_value,
														 pressed, x, y, st)
				Result := return_value(v)
			end
		end

	-- Callbacks for canvas
	launch_action_fnff (obj: POINTER; posx, posy: REAL_32): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_action_fnff(posx, posy)
				Result := return_value(v)
			end
		end

	launch_focus_cb_fni (obj: POINTER; focus: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_focus(focus)
				Result := return_value(v)
			end
		end

	-- Also for text.
	launch_motion_cb_fniis (obj: POINTER; x, y: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if status.is_not_null then
					create st.from_external_copy(status)
				else
					st := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_motion(x, y, st)
				Result := return_value(v)
			end
		end

	launch_keypress_cb_fnii (obj: POINTER; c, press: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_keypress(c, press)
				Result := return_value(v)
			end
		end

	launch_scroll_cb_fniff (obj: POINTER; op: INTEGER; posx, posy: REAL_32): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_scroll(op, posx, posy)
				Result := return_value(v)
			end
		end

	launch_wheel_cb_fndiis (obj: POINTER; delta: REAL_32; x, y: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if status.is_not_null then
					create st.from_external_copy(status)
				else
					st := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_wheel(delta, x, y, st)
				Result := return_value(v)
			end
		end

	-- Callback for link
	launch_click_cb_fns (obj, url: POINTER): INTEGER
		local
			v, u: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if url.is_not_null then
					create u.from_external_copy(url)
				else
					u := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_click(u)
				Result := return_value(v)
			end
		end

	-- Callbacks for list

	launch_action_fnsii (obj, text: POINTER; item, state: INTEGER): INTEGER
		local
			v, t: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if text.is_not_null then
					create t.from_external_copy(text)
				else
					t := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_action_fnsii(t, item, state)
				Result := return_value(v)
			end
		end

	launch_caret_cb_fniii (obj: POINTER; lin, col, pos: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_caret(lin, col, pos)
				Result := return_value(v)
			end
		end

	launch_dblclick_cb_fnis (obj: POINTER; item: INTEGER; text: POINTER): INTEGER
		local
			v, t: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if text.is_not_null then
					create t.from_external_copy(text)
				else
					t := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_dblclick(item, t)
				Result := return_value(v)
			end
		end

	launch_dragdrop_cb_fniiii (obj: POINTER; drag_id, drop_id, isshift, iscontrol: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_dragdrop(drag_id, drop_id, isshift, iscontrol)
				Result := return_value(v)
			end
		end

	launch_dropdown_cb_fni (obj: POINTER; state: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_dropdown(state)
				Result := return_value(v)
			end
		end

	launch_edit_cb_fnis (obj: POINTER; c: INTEGER; new_value: POINTER): INTEGER
		local
			v, nv: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if new_value.is_not_null then
					create nv.from_external_copy(new_value)
				else
					nv := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_edit(c, nv)
				Result := return_value(v)
			end
		end

	launch_multiselect_cb_fns (obj, value: POINTER): INTEGER
		local
			v, tv: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if value.is_not_null then
					create tv.from_external_copy(value)
				else
					tv := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_multiselect(tv)
				Result := return_value(v)
			end
		end

	-- Callback for spin.
	launch_spin_cb_fni (obj: POINTER; inc: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_spin(inc)
				Result := return_value(v)
			end
		end

	-- Callbacks for text.
	launch_action_fnis (obj: POINTER; c: INTEGER; new_value: POINTER): INTEGER
		local
			v, nv: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if new_value.is_not_null then
					create nv.from_external_copy(new_value)
				else
					nv := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_action_fnis(c, nv)
				Result := return_value(v)
			end
		end

	-- Callbacks for toggle.
	launch_action_fni (obj: POINTER; state: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_action_fni(state)
				Result := return_value(v)
			end
		end

	-- Callbacks for tree
	launch_selection_cb_fnii (obj: POINTER; id, status: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_selection(id, status)
				Result := return_value(v)
			end
		end

	launch_multiselection_cb_fnpi (obj: POINTER; ids: POINTER; n: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_multiselection(ids, n)
				Result := return_value(v)
			end
		end

	launch_multiunselection_cb_fnpi (obj: POINTER; ids: POINTER; n: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_multiunselection(ids, n)
				Result := return_value(v)
			end
		end

	launch_branchopen_cb_fni (obj: POINTER; id: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_branchopen(id)
				Result := return_value(v)
			end
		end

	launch_branchclose_cb_fni (obj: POINTER; id: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_branchclose(id)
				Result := return_value(v)
			end
		end

	launch_executeleaf_cb_fni (obj: POINTER; id: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_executeleaf(id)
				Result := return_value(v)
			end
		end

	launch_showrename_cb_fni (obj: POINTER; id: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_showrename(id)
				Result := return_value(v)
			end
		end

	launch_rename_cb_fnis (obj: POINTER; id: INTEGER; title: POINTER): INTEGER
		local
			v, t: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if title.is_not_null then
					create t.from_external_copy(title)
				else
					t := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_rename(id, t)
				Result := return_value(v)
			end
		end

	launch_noderemoved_cb_fns (obj: POINTER; userdata: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_noderemoved(userdata)
				Result := return_value(v)
			end
		end

	launch_togglevalue_cb_fnii (obj: POINTER; id, state: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_togglevalue(id, state)
				Result := return_value(v)
			end
		end

	-- Callback for menu item ans submenu
	launch_highlight_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_highlight
				Result := return_value(v)
			end
		end

	-- Callbacks for menus
	launch_open_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_open
				Result := return_value(v)
			end
		end

	launch_menuclose_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_menuclose
				Result := return_value(v)
			end
		end

	-- Drag&Drop callbacks
	launch_dragbegin_cb_fnii (obj: POINTER; x, y: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_dragbegin(x, y)
				Result := return_value(v)
			end
		end

	launch_dragdatasize_cb_fns (obj, type: POINTER): INTEGER
		local
			t: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if type.is_not_null then
					create t.from_external_copy(type)
				else
					t := ""
				end
				
				iup_widget := objects.at(obj)
				Result := iup_widget.execute_dragdatasize(t)
			end
		end

	launch_dragdata_cb_fnsvi (obj, type, data: POINTER; size: INTEGER): INTEGER
		local
			v, t: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if type.is_not_null then
					create t.from_external_copy(type)
				else
					t := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_dragdata(t, data, size)
				Result := return_value(v)
			end
		end

	launch_dragend_cb_fni (obj: POINTER; action: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_dragend(action)
				Result := return_value(v)
			end
		end

	launch_dropdata_cb_fnsviii (obj, type, data: POINTER; size, x, y: INTEGER): INTEGER
		local
			v, t: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if type.is_not_null then
					create t.from_external_copy(type)
				else
					t := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_dropdata(t, data, size, x, y)
				Result := return_value(v)
			end
		end

	launch_dropmotion_cb_fniis (obj: POINTER; x, y: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if status.is_not_null then
					create st.from_external_copy(status)
				else
					st := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_dropmotion(x, y, st)
				Result := return_value(v)
			end
		end

	-- Callback for recent file menu

	launch_recent_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_recent
				Result := return_value(v)
			end
		end

	-- Callback for get param

	launch_param_cb_fniv (obj: POINTER; param_index: INTEGER; user_data: POINTER): INTEGER
		do
			if get_param /= Void then
				Result := get_param.execute_param(obj, param_index, user_data)
			else
				Result := 1
			end
		end

	-- Callbacks for flat button

	launch_flat_action_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_flat_action
				Result := return_value(v)
			end
		end

	launch_flat_button_cb_fniiiis (obj: POINTER; button, pressed, x, y: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if status.is_not_null then
					create st.from_external_copy(status)
				else
					st := ""
				end

				iup_widget := objects.at(obj)
				v := iup_widget.execute_flat_button(button.to_character.decimal_value,
																pressed, x, y, st)
				Result := return_value(v)
			end
		end

	launch_flat_focus_cb_fni (obj: POINTER; focus: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_flat_focus(focus)
				Result := return_value(v)
			end
		end

	launch_flat_enterwindow_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_flat_enterwindow
				Result := return_value(v)
			end
		end

	launch_flat_leavewindow_cb_fn (obj: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_flat_leavewindow
				Result := return_value(v)
			end
		end

	-- Callbacks for cells
	
	launch_draw_cb_fniiiiiic (obj: POINTER; line, column, xmin, xmax, ymin, ymax: INTEGER; canvas: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_draw(line, column, xmin, xmax, ymin, ymax, canvas)
				Result := return_value(v)
			end
		end
	
	launch_height_cb_fni (obj: POINTER; line: INTEGER): INTEGER
		local
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				Result := iup_widget.execute_height(line)
			end
		end
			
	launch_hspan_cb_fnii (obj: POINTER; line, column: INTEGER): INTEGER
		local
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				Result := iup_widget.execute_hspan(line, column)
			end
		end

	launch_mouseclick_cb_fniiiiiis (obj: POINTER; button, pressed, line, column, x, y: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if status.is_not_null then
					create st.from_external_copy(status)
				else
					st := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_mouseclick(button.to_character.decimal_value,
															  pressed, line, column, x, y, st)
				Result := return_value(v)
			end
		end
		
	launch_mousemotion_cb_fniiiis (obj: POINTER; line, column, x, y: INTEGER; r: POINTER): INTEGER
		local
			v, rs: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if r.is_not_null then
					create rs.from_external_copy(r)
				else
					rs := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_mousemotion(line, column, x, y, rs)
				Result := return_value(v)
			end
		end

	launch_ncols_cb_fn (obj: POINTER): INTEGER
		local
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				Result := iup_widget.execute_ncols
			end
		end
	
	launch_nlines_cb_fn (obj: POINTER): INTEGER
		local
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				Result := iup_widget.execute_nlines
			end
		end
	
	launch_scrolling_cb_fnii (obj: POINTER; line, column: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_scrolling(line, column)
				Result := return_value(v)
			end
		end

	launch_vspan_cb_fnii (obj: POINTER; line, column: INTEGER): INTEGER
		local
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				Result := iup_widget.execute_vspan(line, column)
			end
		end
	
	launch_width_cb_fni (obj: POINTER; column: INTEGER): INTEGER
		local
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				Result := iup_widget.execute_width(column)
			end
		end

	-- Callbacks for color bar

	launch_cell_fni (obj: POINTER; cell: INTEGER): INTEGER
		local
			cl: TUPLE[INTEGER, INTEGER, INTEGER]
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				cl := iup_widget.execute_cell(cell)

				if cl /= Void then
					Result := int_encode_color (cl.item_1,
														 cl.item_2,
														 cl.item_3)	
				else
					Result := -1
				end
			end
		end

	launch_extended_fni (obj: POINTER; cell: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_extended(cell)
				Result := return_value(v)
			end
		end

	launch_select_fnii (obj: POINTER; cell, type: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_select(cell, type)
				Result := return_value(v)
			end
		end

	launch_switch_fnii (obj: POINTER; prim_cell, sec_cell: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_switch(prim_cell, sec_cell)
				Result := return_value(v)
			end
		end

	-- Callbacks for Matrix

	launch_action_fniiiis (obj: POINTER; key, lin, col, edition: INTEGER; value: POINTER): INTEGER
		local
			v, vs: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if value.is_not_null then
					create vs.from_external_copy(value)
				else
					vs := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_action_fniiiis(key, lin, col, edition, vs)
				Result := return_value(v)
			end
		end

	launch_click_fniis (obj: POINTER; lin, col: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if status.is_not_null then
					create st.from_external_copy(status)
				else
					st := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_click_fniis(lin, col, st)
				Result := return_value(v)
			end
		end

	launch_colresize_fni (obj: POINTER; col: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_colresize(col)
				Result := return_value(v)
			end
		end

	launch_release_fniis (obj: POINTER; lin, col: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if status.is_not_null then
					create st.from_external_copy(status)
				else
					st := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_release(lin, col, st)
				Result := return_value(v)
			end
		end

	launch_resizematrix_fnii (obj: POINTER; width, height: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_resizematrix(width, height)
				Result := return_value(v)
			end
		end

	launch_mousemove_fnii (obj: POINTER; lin, col: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_mousemove(lin, col)
				Result := return_value(v)
			end
		end

	launch_enteritem_fnii (obj: POINTER; lin, col: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_enteritem(lin, col)
				Result := return_value(v)
			end
		end

	launch_leaveitem_fnii (obj: POINTER; lin, col: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_leaveitem(lin, col)
				Result := return_value(v)
			end
		end

	launch_scrolltop_fnii (obj: POINTER; lin, col: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_scrolltop(lin, col)
				Result := return_value(v)
			end
		end

	launch_bgcolor_fniivvv (obj: POINTER; lin, col: INTEGER; red, green, blue: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_bgcolor(lin, col, red, green, blue)
				Result := return_value(v)
			end
		end

	launch_fgcolor_fniivvv (obj: POINTER; lin, col: INTEGER; red, green, blue: POINTER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_fgcolor(lin, col, red, green, blue)
				Result := return_value(v)
			end
		end

	launch_font_fnii (obj: POINTER; lin, col: INTEGER): POINTER
		local
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				Result := iup_widget.execute_font(lin, col).to_external
			end
		end

	launch_type_fnii (obj: POINTER; lin, col: INTEGER): POINTER
		local
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				Result := iup_widget.execute_type(lin, col).to_external
			end
		end

	launch_dropcheck_fnii (obj: POINTER; lin, col: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_dropcheck(lin, col)
				Result := return_value(v)
			end
		end

	launch_translatevalue_fniis (obj: POINTER; lin, col: INTEGER; value: POINTER): POINTER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if value.is_not_null then
					create v.from_external_copy(value)
				else
					v := ""
				end
				
				iup_widget := objects.at(obj)
				Result := iup_widget.execute_translatevalue(lin, col, v).to_external
			end
		end
	
	launch_togglevalue_fniii (obj: POINTER; lin, col, status: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_togglevalue_fniii(lin, col, status)
				Result := return_value(v)
			end
		end

	launch_drop_fnnii (obj, drop: POINTER; lin, col: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
			iup_drop: IUP_DROP
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)

				if objects.has(drop) then
					if iup_drop ?:= objects.at(drop) then
						iup_drop ::= objects.at(drop)
					end
				else
					create iup_drop.drop_widget(drop)
				end
				
				v := iup_widget.execute_drop(iup_drop, lin, col)
				Result := return_value(v)
			end
		end

	launch_menudrop_fnnii (obj, drop: POINTER; lin, col: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
			iup_drop: IUP_DROP
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)

				if objects.has(drop) then
					if iup_drop ?:= objects.at(drop) then
						iup_drop ::= objects.at(drop)
					end
				else
					create iup_drop.drop_widget(drop)
				end
				
				v := iup_widget.execute_menudrop(iup_drop, lin, col)
				Result := return_value(v)
			end
		end

	launch_dropselect_fniinsii (obj: POINTER; lin, col: INTEGER; drop, t: POINTER; i, v: INTEGER): INTEGER
		local
			r, ts: STRING
			iup_widget: IUP_WIDGET
			iup_drop: IUP_DROP
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)

				if t.is_not_null then
					create ts.from_external_copy(t)
				else
					ts := ""
				end

				if objects.has(drop) then
					if iup_drop ?:= objects.at(drop) then
						iup_drop ::= objects.at(drop)
					end
				else
					create iup_drop.drop_widget(drop)
				end
				
				r := iup_widget.execute_dropselect(lin, col, iup_drop, ts, i, v)
				Result := return_value(r)
			end
		end

	launch_edition_fniiii (obj: POINTER; lin, col, mode, update: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_edition(lin, col, mode, update)
				Result := return_value(v)
			end
		end

	launch_value_fnii (obj: POINTER; lin, col: INTEGER): POINTER
		local
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				Result := iup_widget.execute_value(lin, col).to_external
			end
		end

	launch_value_edit_fniis (obj: POINTER; lin, col: INTEGER; newval: POINTER): INTEGER
		local
			v, nv: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if newval.is_not_null then
					create nv.from_external_copy(newval)
				else
					nv := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_value_edit(lin, col, nv)
				Result := return_value(v)
			end
		end

	launch_mark_fnii (obj: POINTER; lin, col: INTEGER): INTEGER
		local
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				Result := iup_widget.execute_mark(lin, col)
			end
		end

	launch_markedit_fniii (obj: POINTER; lin, col, marked: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_markedit(lin, col, marked)
				Result := return_value(v)
			end
		end

	-- Flat tabs
	launch_flat_motion_cb_fniis (obj: POINTER; x, y: INTEGER; status: POINTER): INTEGER
		local
			v, st: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then

				if status.is_not_null then
					create st.from_external_copy(status)
				else
					st := ""
				end
				
				iup_widget := objects.at(obj)
				v := iup_widget.execute_flat_motion(x, y, st)
				Result := return_value(v)
			end
		end

	-- Drop button

	launch_dropshow_cb_fni (obj: POINTER; state: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_dropshow(state)
				Result := return_value(v)
			end
		end

	-- Dial

	launch_button_press_cb_fnd (obj: POINTER; angle: REAL_64): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_button_press(angle)
				Result := return_value(v)
			end
		end

	launch_button_release_cb_fnd (obj: POINTER; angle: REAL_64): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_button_release(angle)
				Result := return_value(v)
			end
		end

	launch_mousemove_cb_fnd (obj: POINTER; angle: REAL_64): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_mousemove_fnd(angle)
				Result := return_value(v)
			end
		end

	-- Color browser

	launch_change_cb_fnvvv (obj: POINTER; red, green, blue: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_change(red, green, blue)
				Result := return_value(v)
			end
		end

	launch_drag_cb_fnvvv (obj: POINTER; red, green, blue: INTEGER): INTEGER
		local
			v: STRING
			iup_widget: IUP_WIDGET
		do
			if objects.has(obj) then
				iup_widget := objects.at(obj)
				v := iup_widget.execute_drag(red, green, blue)
				Result := return_value(v)
			end
		end

feature {IUP_DIALOG}

	get_drop_button_for_dialog (dlg: IUP_DIALOG): IUP_DROP_BUTTON
		local
			p: POINTER
			iup_drop_button: IUP_DROP_BUTTON
		do
			p := get_attribute_ihandle(dlg, "DROPBUTTON")
			
			if objects.has(p) then
				if iup_drop_button ?:= objects.at(p) then
					iup_drop_button ::= objects.at(p)
				end
			end

			Result := iup_drop_button
		end

feature {}

	idle_action: FUNCTION[TUPLE, STRING]
	objects:     HASHED_DICTIONARY[IUP_WIDGET, POINTER]
	callbacks:   HASHED_DICTIONARY[IUP_WIDGET, POINTER]

	get_param: IUP_GET_PARAM

	-- Conversion

	yesno_to_boolean (value: STRING): BOOLEAN
		do
			if value.is_equal("YES") then
				Result := True
			else
				Result := False
			end
		end

	boolean_to_yesno (value: BOOLEAN): STRING
		do
			if value then
				Result := "YES"
			else
				Result := "NO"
			end
		end

	components_of (size: STRING; separator: CHARACTER): TUPLE[INTEGER, INTEGER]
		local
			i, c: INTEGER
			width, height: STRING
			tup: TUPLE[INTEGER, INTEGER]
		do
			if size.has(separator) then
				i := size.index_of(separator, 1)
				c := size.count
				
				if not i.is_equal(1) then
					width := size.substring(1, i - 1)
				else
					width := "0"
				end
				
				if not i.is_equal(c) then
					height := size.substring(i + 1, c)
				else
					height := "0"
				end

				tup := [width.to_integer, height.to_integer]
				Result := tup
			else
				io.put_string("Unable to get the components %N")
			end
		end

	convert_string_to_array (data: STRING): NATIVE_ARRAY[CHARACTER]
		local
			l, u: INTEGER;
			v: CHARACTER
			arg: NATIVE_ARRAY[CHARACTER]
			x: INTEGER
		do
			l := data.lower
			u := data.upper
			arg := arg.calloc(u)
			
			from
				x := l
         until
				x = u
         loop
				v := data.item(x)
				arg.put(v, x - 1)
				x := x + 1
         end
			
			Result := arg
		end

	-- Class name

	get_class_name (wgt: POINTER): STRING
		local
			p: POINTER
			str: STRING
		do
			p := int_get_class_name (wgt)
			
			if p.is_not_null then
				create str.from_external_copy(p)
				Result := str
			else
				Result := ""
			end
		end

	int_get_class_name (wgt: POINTER): POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetClassName"
         }"
      end
	
	-- Loop

	int_loop_step: INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupLoopStep()"
         }"
      end

	int_loop_step_wait: INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupLoopStepWait()"
         }"
      end

	-- PopUp

	int_popup (wdt: POINTER; x, y: INTEGER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupPopup"
         }"
      end

	-- Validations

	is_valid_position (x, y: STRING): BOOLEAN
		local
			xs, ys: BOOLEAN
		do
			if x.is_equal("IUP_LEFT") or
				x.is_equal("IUP_CENTER") or
				x.is_equal("IUP_RIGHT") or
				x.is_equal("IUP_MOUSEPOS") or
				x.is_equal("IUP_CENTERPARENT") or
				x.is_equal("IUP_CURRENT") then
				xs := True
			elseif x.is_integer and x.to_integer >= 0 then
				xs := True
			else
				xs := False
			end

			if y.is_equal("IUP_TOP") or
				y.is_equal("IUP_CENTER") or
				y.is_equal("IUP_BOTTOM") or
				y.is_equal("IUP_MOUSEPOS") or
				y.is_equal("IUP_CENTERPARENT") or
				y.is_equal("IUP_CURRENT") then
				ys := True
			elseif y.is_integer and y.to_integer >= 0 then
				ys := True
			else
				ys := False
			end

			if xs and ys then
				Result := True
			else
				Result := False
			end
		end

	is_valid_buttons (value: STRING): BOOLEAN
		do
			if value.is_equal("OK") or
				value.is_equal("OKCANCEL") or
				value.is_equal("RETRYCANCEL") or
				value.is_equal("YESNO") or
				value.is_equal("YESNOCANCEL") then
				Result := True
			else
				Result := False
			end
		end

	-- Help

	int_help (u: POINTER): INTEGER
		external "plug_in"
      alias "{
			location: "${sys}/plugins"
			module_name: "iup"
			feature_name: "IupHelp"
			}"
      end
	
	-- Global attributes
	
	int_set_global (name: POINTER; value: POINTER)
		external "plug_in"
      alias "{
			location: "${sys}/plugins"
			module_name: "iup"
			feature_name: "IupSetGlobal"
			}"
      end

	int_get_global (name: POINTER): POINTER
		external "plug_in"
      alias "{
			location: "${sys}/plugins"
			module_name: "iup"
			feature_name: "IupGetGlobal"
			}"
      end

	-- Focus

	int_get_focus: POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetFocus()"
         }"
      end

	-- Destroy
	int_destroy (wgt: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupDestroy"
         }"
      end

	-- Callbacks

	widget_for_object (wgt: POINTER): IUP_WIDGET
		do
			if objects.has(wgt) then
				Result := objects.at(wgt)
			end
		end
	
	return_value (type: STRING): INTEGER
		do
			if type /= Void then
				if (type.is_equal("IUP_IGNORE")) then
					Result := -1
				elseif (type.is_equal("IUP_DEFAULT")) then
					Result := -2
				elseif (type.is_equal("IUP_CLOSE")) then
					Result := -3
				elseif (type.is_equal("IUP_CONTINUE")) then
					Result := -4
				end
			else
				Result := -1
			end
		end

	int_set_callback (object: POINTER; name: POINTER; type: POINTER; operation: INTEGER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "connect_callback"
         }"
      end

	int_set_function (object: POINTER; operation: INTEGER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "connect_function"
         }"
      end

	-- Hierarchy and management.
	
	int_append (control: POINTER; new_child: POINTER): POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupAppend"
         }"
      end

	int_detach (control: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupDetach"
         }"
      end
	
	int_insert (control: POINTER; ref_child: POINTER; new_child: POINTER): POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupInsert"
         }"
      end

	int_reparent (child: POINTER; new_parent: POINTER; ref_child: POINTER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupReparent"
         }"
      end

	int_get_parent (child: POINTER): POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetParent"
         }"
      end

	int_get_child (control: POINTER; position: INTEGER): POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetChild"
         }"
      end

	int_get_child_pos (control: POINTER; child: POINTER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetChildPos"
         }"
      end

	int_get_child_count (control: POINTER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetChildCount"
         }"
      end

	int_get_next_child (control: POINTER; child: POINTER): POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetNextChild"
         }"
      end

	int_get_brother (control: POINTER): POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetBrother"
         }"
      end

	int_get_dialog (control: POINTER): POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetDialog"
         }"
      end

	int_get_dialog_child (control: POINTER; child: POINTER): POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetDialogChild"
         }"
      end

	int_refresh (control: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupRefresh"
         }"
      end

	int_refresh_children (control: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupRefreshChildren"
         }"
      end

	int_update (control: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupUpdate"
         }"
      end

	int_update_children (control: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupUpdateChildren"
         }"
      end

	int_redraw (control: POINTER; ch: INTEGER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupRedraw"
         }"
      end

	int_convert_xy_to_pos (control: POINTER; x, y: INTEGER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupConvertXYToPos"
         }"
      end
	
	-- Attributes
	
   int_set_attribute (wgt: POINTER; name: POINTER; value: POINTER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetAttribute"
         }"
      end

   int_set_str_attribute (wgt: POINTER; name: POINTER; value: POINTER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetStrAttribute"
         }"
      end

	int_set_attribute_id (wgt: POINTER; name: POINTER; id: INTEGER; value: POINTER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetAttributeId"
         }"
      end

   int_set_str_attribute_id (wgt: POINTER; name: POINTER; id: INTEGER; value: POINTER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetStrAttributeId"
         }"
      end

	int_set_attribute_id2 (wgt: POINTER; name: POINTER; lin: INTEGER; col: INTEGER; value: POINTER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetAttributeId2"
         }"
      end

   int_set_str_attribute_id2 (wgt: POINTER; name: POINTER; lin: INTEGER; col: INTEGER; value: POINTER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetStrAttributeId2"
         }"
      end

	int_set_int (wgt: POINTER; name: POINTER; value: INTEGER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetInt"
         }"
      end

	int_set_float (wgt: POINTER; name: POINTER; value: REAL_32)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetFloat"
         }"
      end

	int_set_double (wgt: POINTER; name: POINTER; value: REAL_64)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetDouble"
         }"
      end

	int_set_rgb (wgt: POINTER; name: POINTER; r: CHARACTER; g: CHARACTER; b: CHARACTER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetRGB"
         }"
      end

	int_set_int_id (wgt: POINTER; name: POINTER; id: INTEGER; value: INTEGER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetIntId"
         }"
      end

	int_set_float_id (wgt: POINTER; name: POINTER; id: INTEGER; value: REAL_32)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetFloatId"
         }"
      end

	int_set_double_id (wgt: POINTER; name: POINTER; id: INTEGER; value: REAL_64)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetDoubleId"
         }"
      end

	int_set_rgb_id (wgt: POINTER; name: POINTER; id: INTEGER; r: CHARACTER; g: CHARACTER; b: CHARACTER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetRGBId"
         }"
      end

	int_set_int_id2 (wgt: POINTER; name: POINTER; lin: INTEGER; col: INTEGER; value: INTEGER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetIntId2"
         }"
      end

	int_set_float_id2 (wgt: POINTER; name: POINTER; lin: INTEGER; col: INTEGER; value: REAL_32)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetFloatId2"
         }"
      end

	int_set_double_id2 (wgt: POINTER; name: POINTER; lin: INTEGER; col: INTEGER; value: REAL_64)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetDoubleId2"
         }"
      end

	int_set_rgb_id2 (wgt: POINTER; name: POINTER; lin: INTEGER; col: INTEGER; r: CHARACTER; g: CHARACTER; b: CHARACTER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetRGBId2"
         }"
      end

	int_reset_attribute (wgt: POINTER; name: POINTER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupResetAttribute"
         }"
      end

	int_set_attribute_handle (wgt: POINTER; name: POINTER; wgt_named: POINTER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetAttributeHandle"
         }"
      end

	int_get_attribute (wgt: POINTER; name: POINTER): POINTER
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetAttribute"
         }"
      end

	int_get_attribute_id (wgt: POINTER; name: POINTER; id: INTEGER): POINTER
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetAttributeId"
         }"
      end

	int_get_attribute_id2 (wgt: POINTER; name: POINTER; lin: INTEGER; col: INTEGER): POINTER
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetAttributeId2"
         }"
      end

	int_get_int (wgt: POINTER; name: POINTER): INTEGER
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetInt"
         }"
      end

	int_get_int_int (wgt: POINTER; name: POINTER; i1: POINTER; i2: POINTER): INTEGER
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetIntInt"
         }"
      end

	int_get_int2 (wgt: POINTER; name: POINTER): INTEGER
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetInt2"
         }"
      end

	int_get_float (wgt: POINTER; name: POINTER): REAL_32
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetFloat"
         }"
      end

	int_get_double (wgt: POINTER; name: POINTER): REAL_64
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetDouble"
         }"
      end

	int_get_rgb (wgt: POINTER; name, r, g, b: POINTER)
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetRGB"
         }"
      end

	int_get_attribute_handle (wgt: POINTER; name: POINTER): POINTER
      external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetAttributeHandle"
         }"
      end

	-- Key codes

	int_is_print_key(key: INTEGER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_isprint"
         }"
      end

	int_is_x_key(key: INTEGER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_isXkey"
         }"
      end
	
	int_is_shift_x_key(key: INTEGER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_isShiftXkey"
         }"
      end

	int_is_ctrl_x_key(key: CHARACTER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
			feature_name: "iup_isCtrlXkey"
         }"
      end

	int_is_alt_x_key(key: CHARACTER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_isAltXkey"
         }"
      end

	int_is_sys_x_key(key: CHARACTER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_isSysXkey"
         }"
      end

	-- Mouse buttons

	int_is_shift(status: NATIVE_ARRAY[CHARACTER]): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_isshift"
         }"
      end

	int_is_control(status: NATIVE_ARRAY[CHARACTER]): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_iscontrol"
         }"
      end

	int_is_button_1(status: NATIVE_ARRAY[CHARACTER]): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_isbutton1"
         }"
      end

	int_is_button_2(status: NATIVE_ARRAY[CHARACTER]): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_isbutton2"
         }"
      end

	int_is_button_3(status: NATIVE_ARRAY[CHARACTER]): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_isbutton3"
         }"
      end

	int_is_button_4(status: NATIVE_ARRAY[CHARACTER]): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_isbutton4"
         }"
      end

	int_is_button_5(status: NATIVE_ARRAY[CHARACTER]): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_isbutton5"
         }"
      end

	int_is_double(status: NATIVE_ARRAY[CHARACTER]): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_isdouble"
         }"
      end

	int_is_alt(status: NATIVE_ARRAY[CHARACTER]): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_isalt"
         }"
      end

	int_is_sys(status: NATIVE_ARRAY[CHARACTER]): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "iup_issys"
         }"
      end

	-- CD

	int_use_context_plus(status: INTEGER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "cdUseContextPlus"
         }"
      end

	int_encode_color (r, g, b: INTEGER): INTEGER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "cdEncodeColor"
         }"
      end

	-- Languages

	int_set_language_string (n, v: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetLanguageString"
         }"
		end

	int_store_language_string (n, v: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupStoreLanguageString"
         }"
		end

	int_get_language_string(n: POINTER): POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupGetLanguageString"
         }"
		end

	int_set_language_pack (p: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupSetLanguagePack"
         }"
		end

	-- Copy attributes

	int_copy_attributes (s, d: POINTER)
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupCopyAttributes"
         }"
		end

end -- class IUP

-- The MIT License (MIT)

-- Copyright (c) 2016, 2017, 2018, 2019, 2022 by German A. Arias

-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in 
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.
